﻿//#define USE_TIMER

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleTest
{
    
    class Directory
    {
        

        public static void DirectoryInfoFun()
        {
            System.IO.DriveInfo DriveEntity=new System.IO.DriveInfo("c");
            Console.WriteLine("根目录：" + DriveEntity.RootDirectory + " \n " + DriveEntity.TotalSize);

        }

        //文件系统监视器
        public static void FileSysWatcherFun()
        {
            System.IO.FileSystemWatcher watcher = new System.IO.FileSystemWatcher();
            watcher.Path = System.IO.Directory.GetCurrentDirectory();
            
            // 指定要在文件或文件夹中监视的更改类型
            //此枚举有一个 FlagsAttribute 特性，通过该特性可使其成员值按位组合。
            watcher.NotifyFilter = System.IO.NotifyFilters.LastAccess | System.IO.NotifyFilters.DirectoryName | System.IO.NotifyFilters.FileName |
                System.IO.NotifyFilters.LastWrite | System.IO.NotifyFilters.Size; 
            
            
            //watcher.Filter = "*.txt";

            //监视子目录及其文件
            watcher.IncludeSubdirectories = true;
            watcher.EnableRaisingEvents = true;
            //#region 不适用定时器的情况

            #if(USE_TIMER)
            watcher.Changed += new System.IO.FileSystemEventHandler(OnChange);
            watcher.Created += new System.IO.FileSystemEventHandler(OnChange);
            watcher.Deleted += new System.IO.FileSystemEventHandler(OnChange);
            //watcher.Renamed += new RenamedEventHandler(OnRenamed);

            
            //#endregion


            //#region 使用定时器的方法
            #else
            watcher.Changed += new System.IO.FileSystemEventHandler(OnChangeWithTimer);
            watcher.Created += new System.IO.FileSystemEventHandler(OnChangeWithTimer);
            watcher.Deleted += new System.IO.FileSystemEventHandler(OnChangeWithTimer);
            if (m_timer == null)
            {
                //设置timer要执行的方法
                m_timer = new System.Threading.Timer(new System.Threading.TimerCallback(Directory.FileChanged), null, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
            }
            #endif
            //#endregion



            Console.WriteLine(watcher.Path);
            Console.WriteLine("press Q to stop the program......");

            while (System.Console.Read()!= 'q') ;
        }

        //文件改变时事件处理程序
        public static void OnChange(object source,System.IO.FileSystemEventArgs e)
        {
            //该方法执行了两次
            //公共文件系统操作可能会引发多个事件。例如，将文件从一个目录移到另一个目录时，
            //可能会引发若干 OnChanged 以及一些 OnCreated 和 OnDeleted 事件。移动文件是一个包含多个简单操作的复杂操作，因此会引发多个事件。
            //同样，有些应用程序（例如，防病毒软件）可能会导致可由 FileSystemWatcher 检测到的其他文件系统事件。
            
            System.Console.WriteLine("File  "+e.FullPath+"\n Change type   "+e.ChangeType);
        }


        #region 使用定时器效果相同，并没有改变
        //使用定时器解决文件在修改时事件多次触发的问题
        //定义time
        private static System.Threading.Timer m_timer = null;
        private static int TimeoutMillis = 2000; //定时器触发间隔
        //用列表记录更改文件的内容
        private static System.Collections.Generic.List<string> m_ListStr = new List<string>();

        //timer 事件中来具体处理文件更改
        public static void FileChanged(object state)
        {
            System.Collections.Generic.List<string> list = new List<string>();
            System.Threading.Mutex mutex = new System.Threading.Mutex(false, "FSW");
            mutex.WaitOne();
            list.AddRange(m_ListStr);
            mutex.ReleaseMutex();

            foreach (string str in list)
            {
                System.Console.WriteLine(str);
            }
        }

        //使用定时器后的文件改变事件处理程序
        //此时仅仅记录文件更改而不会对文件更改进行处理
        public static void OnChangeWithTimer(object sender, System.IO.FileSystemEventArgs e)
        {
            System.Threading.Mutex mutex = new System.Threading.Mutex(false, "FSW");
            mutex.WaitOne();
            if (!m_ListStr.Contains(e.Name))
            {
                m_ListStr.Add("File  " + e.FullPath + "\n Change type   " + e.ChangeType);
            }
            mutex.ReleaseMutex();

            //重新设置定时器的触发间隔，并且仅仅触发一次
            m_timer.Change(TimeoutMillis, System.Threading.Timeout.Infinite);

        }
        #endregion
    }
}
